home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 July: Mac OS SDK / Dev.CD Jul 96 SDK / Dev.CD Jul 96 SDK1.toast / Development Kits (Disc 1) / OpenDoc Development Framework / ODFDev / ODF / OS / FWGraphx / Sources / PRPictur.cpp < prev    next >
Encoding:
Text File  |  1996-04-25  |  14.1 KB  |  546 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                PRPictur.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #ifndef SLPALETE_H
  13. #include "SLPalete.h"
  14. #endif
  15.  
  16. #ifndef FWODEXCE_H
  17. #include "FWODExce.h"
  18. #endif
  19.  
  20. #ifndef FWBITMAP_H
  21. #include "FWBitmap.h"
  22. #endif
  23.  
  24. #ifndef FWWINRES_H
  25. #include "FWWinRes.h"
  26. #endif
  27.  
  28. #ifndef FWSTRMRW_H
  29. #include "FWStrmRW.h"
  30. #endif
  31.  
  32. #ifndef FWRESOUR_H
  33. #include "FWResour.h"
  34. #endif
  35.  
  36. #ifndef FWGC_H
  37. #include "FWGC.h"
  38. #endif
  39.  
  40. #ifndef PRGDEV_H
  41. #include "PRGDev.h"
  42. #endif
  43.  
  44. #ifndef FWSOMENV_H
  45. #include "FWSOMEnv.h"
  46. #endif
  47.  
  48. #ifndef PRPICTUR_H
  49. #include "PRPictur.h"
  50. #endif
  51.  
  52. #ifndef FWMEMMGR_H
  53. #include "FWMemMgr.h"
  54. #endif
  55.  
  56. #ifndef FWEXCEPT_H
  57. #include "FWExcept.h"
  58. #endif
  59.  
  60. //========================================================================================
  61. //    RunTime Info
  62. //========================================================================================
  63.  
  64. #ifdef FW_BUILD_MAC
  65. #pragma segment FWGraphics_Picture
  66. #endif
  67.  
  68. FW_DEFINE_AUTO(FW_CPrivPictureRep)
  69.  
  70. //----------------------------------------------------------------------------------------
  71. //    Placeable (Aldus) metafile definitions for Windows
  72. //----------------------------------------------------------------------------------------
  73.  
  74. #ifdef FW_BUILD_WIN
  75.  
  76. #pragma pack(push,1)
  77.  
  78. struct RECT16
  79. {
  80.     short   left;
  81.     short   top;
  82.     short   right;
  83.     short   bottom;
  84. };
  85.  
  86. struct SAldusHeader
  87. {
  88.     DWORD   key;
  89.     WORD    hmf;
  90.     RECT16    bbox;
  91.     WORD    inch;
  92.     DWORD   reserved;
  93.     WORD    checksum;
  94. } ;
  95.  
  96. #pragma pack(pop)
  97.  
  98. const DWORD kAldusKey =    0x9AC6CDD7l;
  99.  
  100. #endif
  101.  
  102. //----------------------------------------------------------------------------------------
  103. //    FW_CPrivPictureRep::FW_CPrivPictureRep
  104. //----------------------------------------------------------------------------------------
  105. //    From Stream: we own the picture
  106.  
  107. FW_CPrivPictureRep::FW_CPrivPictureRep(FW_CReadableStream& stream) :
  108.     fOwnPicture(TRUE),
  109.     fPlatformPict(NULL)
  110. {
  111. #ifdef FW_BUILD_MAC
  112.     fMacLockCount    = 0;
  113. #endif
  114.  
  115.     PrivReadFrom(stream);
  116.     
  117.     FW_END_CONSTRUCTOR
  118. }
  119.  
  120. //----------------------------------------------------------------------------------------
  121. //    FW_CPrivPictureRep::FW_CPrivPictureRep
  122. //----------------------------------------------------------------------------------------
  123. //    From File: we own the picture
  124.  
  125. FW_CPrivPictureRep::FW_CPrivPictureRep(FW_OResourceFile* resourceFile, FW_ResourceId resId) :
  126.     fOwnPicture(TRUE),
  127.     fPlatformPict(NULL)
  128. {
  129.  
  130. #ifdef FW_BUILD_MAC
  131.     fMacLockCount    = 0;
  132. #endif
  133.  
  134. #ifdef FW_BUILD_MAC
  135. // [JEL] ??? Is there a good reason why the mac version doesn't use the specified resourceFile ???
  136. FW_UNUSED(resourceFile);
  137.     FW_PlatformPict newPict = ::GetPicture(resId);
  138.     if (newPict == NULL)
  139.     {
  140.         FW_FailOnError(::ResError());
  141.         FW_Failure(FW_xMemoryExhausted);        
  142.     }
  143.  
  144.     // Because of CFM we have to detach the resource
  145.     ::DetachResource((Handle)newPict);
  146.     AdoptPlatformPict(newPict);
  147. #endif
  148.  
  149. #ifdef FW_BUILD_WIN
  150.     FW_SOMEnvironment ev;
  151.     FW_PResource resource(ev, resourceFile, resId, FW_kPicture);
  152.     FW_PResourceSink sink(ev, resource);
  153.     FW_CReadableStream stream(sink);
  154.     PrivReadFrom(stream);
  155. #endif
  156.  
  157.     FW_END_CONSTRUCTOR
  158. }
  159.  
  160. //----------------------------------------------------------------------------------------
  161. //    FW_CPrivPictureRep::FW_CPrivPictureRep
  162. //----------------------------------------------------------------------------------------
  163. //    From platform pict: we don't own the picture
  164.  
  165. FW_CPrivPictureRep::FW_CPrivPictureRep(FW_PlatformPict platformPict) :
  166.     fOwnPicture(FALSE),
  167.     fPlatformPict(platformPict)
  168. {
  169. #ifdef FW_BUILD_MAC
  170.     fMacLockCount    = 0;
  171. #endif
  172.     FW_END_CONSTRUCTOR
  173. }
  174.  
  175. //----------------------------------------------------------------------------------------
  176. //    FW_CPrivPictureRep::FW_CPrivPictureRep
  177. //----------------------------------------------------------------------------------------
  178. //    From another Pict: we own the picture (a copy is made)
  179.  
  180. FW_CPrivPictureRep::FW_CPrivPictureRep(const FW_CPrivPictureRep& other) :
  181.     fOwnPicture(TRUE),
  182.     fPlatformPict(NULL)
  183. {
  184.     FW_PlatformPict otherPict = other.GetPlatformPict();
  185.     
  186. #ifdef FW_BUILD_MAC
  187.     fPlatformPict = (FW_PlatformPict) FW_CMemoryManager::CopySystemHandle((FW_PlatformHandle)otherPict);
  188.     fMacLockCount    = 0;
  189. #endif
  190. #ifdef FW_BUILD_WIN
  191.     fPlatformPict = ::CopyEnhMetaFile(otherPict, NULL);
  192. #endif
  193.     
  194.     if (fPlatformPict == 0)
  195.         FW_Failure(FW_xMemoryExhausted);
  196.  
  197.     FW_END_CONSTRUCTOR
  198. }
  199.  
  200. //----------------------------------------------------------------------------------------
  201. //    FW_CPrivPictureRep::~FW_CPrivPictureRep
  202. //----------------------------------------------------------------------------------------
  203.  
  204. FW_CPrivPictureRep::~FW_CPrivPictureRep()
  205. {
  206.     FW_START_DESTRUCTOR
  207.      PrivDisposePict();
  208. }
  209.  
  210. //----------------------------------------------------------------------------------------
  211. //    FW_CPrivPictureRep::Write
  212. //----------------------------------------------------------------------------------------
  213.  
  214. void FW_CPrivPictureRep::Write(FW_CWritableStream& stream)
  215. {
  216. #ifdef FW_BUILD_MAC
  217.     unsigned long picSize = FW_CMemoryManager::GetSystemHandleSize((FW_PlatformHandle)fPlatformPict);
  218.     stream << picSize;
  219.  
  220.     MacLock();
  221.     
  222.     FW_TRY
  223.     {
  224.         stream.Write(*fPlatformPict, picSize);
  225.     }
  226.     FW_CATCH_BEGIN
  227.     FW_CATCH_EVERYTHING()
  228.     {
  229.         MacUnlock();
  230.         FW_THROW_SAME();
  231.     }
  232.     FW_CATCH_END
  233.  
  234.     MacUnlock();    
  235. #endif    
  236. #ifdef FW_BUILD_WIN
  237.     UINT bitsSize = ::GetEnhMetaFileBits(fPlatformPict, 0, NULL);
  238.  
  239.     BYTE* bitsBuf = new BYTE[bitsSize];
  240.     ::GetEnhMetaFileBits(fPlatformPict, bitsSize, bitsBuf);
  241.     
  242.     FW_TRY
  243.     {
  244.         stream.Write(bitsBuf, bitsSize);
  245.     }
  246.     FW_CATCH_BEGIN
  247.     FW_CATCH_EVERYTHING()
  248.     {
  249.         delete[] bitsBuf;
  250.         FW_THROW_SAME();
  251.     }
  252.     FW_CATCH_END
  253.  
  254.     delete[] bitsBuf;
  255. #endif
  256. }
  257.  
  258. //----------------------------------------------------------------------------------------
  259. //    FW_CPrivPictureRep::IsEqual
  260. //----------------------------------------------------------------------------------------
  261.  
  262. FW_Boolean FW_CPrivPictureRep::IsEqual(const FW_CPrivPictureRep& other) const
  263. {
  264.     return fPlatformPict == other.fPlatformPict;
  265. }
  266.  
  267. //----------------------------------------------------------------------------------------
  268. //    FW_CPrivPictureRep::GetPictBounds
  269. //----------------------------------------------------------------------------------------
  270.  
  271. void FW_CPrivPictureRep::GetPictBounds(FW_SRect& bounds) const
  272. {
  273. #ifdef FW_BUILD_MAC
  274.     bounds.left        = FW_kFixed0;
  275.     bounds.top        = FW_kFixed0;
  276.     bounds.right    = FW_IntToFixed((*fPlatformPict)->picFrame.right - (*fPlatformPict)->picFrame.left);
  277.     bounds.bottom    = FW_IntToFixed((*fPlatformPict)->picFrame.bottom - (*fPlatformPict)->picFrame.top);
  278. #endif
  279.  
  280. #ifdef FW_BUILD_WIN
  281.     ENHMETAHEADER emh;
  282.     ::GetEnhMetaFileHeader(fPlatformPict, sizeof(emh), &emh);
  283.     
  284.     // emh.rclBounds is the bounding rectangle in pixels, computed by GDI
  285.  
  286.     bounds.left        = FW_IntToFixed((int) emh.rclBounds.left);
  287.     bounds.top        = FW_IntToFixed((int) emh.rclBounds.top);
  288.     bounds.right    = FW_IntToFixed((int) emh.rclBounds.right);
  289.     bounds.bottom    = FW_IntToFixed((int) emh.rclBounds.bottom);
  290. #endif
  291. }
  292.  
  293. //----------------------------------------------------------------------------------------
  294. //    FW_CPrivPictureRep::GetPictBoundsGC
  295. //----------------------------------------------------------------------------------------
  296.  
  297. void FW_CPrivPictureRep::GetPictBoundsGC(Environment* ev, FW_SGraphicContext& gc, FW_SRect& bounds) const
  298. {    
  299. #ifdef FW_BUILD_MAC
  300.     FW_SPoint size;
  301.     
  302.     FW_PrivGC_DeviceToLogicalSize(ev, gc,
  303.         (*fPlatformPict)->picFrame.right - (*fPlatformPict)->picFrame.left,
  304.         (*fPlatformPict)->picFrame.bottom - (*fPlatformPict)->picFrame.top,
  305.         size);
  306.     // Let go if error    
  307.     bounds.left        =    FW_kFixed0;
  308.     bounds.top        =     FW_kFixed0;
  309.     bounds.right    =     size.x;
  310.     bounds.bottom    =    size.y;
  311. #endif
  312.  
  313. #ifdef FW_BUILD_WIN
  314.     ENHMETAHEADER emh;
  315.     ::GetEnhMetaFileHeader(fPlatformPict, sizeof(emh), &emh);
  316.  
  317.     // emh.rclFrame is the bounding rectangle as specified by the creator, in 0.01 mm units
  318.  
  319.     HDC hDC = gc.fGraphicDevice->GetPlatformCanvas();
  320.  
  321.     int xRes = ::GetDeviceCaps(hDC, LOGPIXELSX);
  322.     int yRes = ::GetDeviceCaps(hDC, LOGPIXELSY);
  323.  
  324.     FW_CPlatformRect plfmBounds;
  325.  
  326.     plfmBounds.left        = emh.rclFrame.left        * xRes / 2540;
  327.     plfmBounds.top        = emh.rclFrame.top        * yRes / 2540;
  328.     plfmBounds.right    = emh.rclFrame.right    * xRes / 2540;
  329.     plfmBounds.bottom    = emh.rclFrame.bottom    * yRes / 2540;
  330.  
  331.     FW_PrivGC_DeviceToLogicalRect(ev, gc, plfmBounds, bounds);
  332.     // Let go if error    
  333. #endif
  334. }
  335.  
  336. //----------------------------------------------------------------------------------------
  337. //    FW_CPrivPictureRep::GetPlatformPict
  338. //----------------------------------------------------------------------------------------
  339.  
  340. FW_PlatformPict    FW_CPrivPictureRep::GetPlatformPict() const
  341. {
  342.     return fPlatformPict;
  343. }
  344.  
  345. //----------------------------------------------------------------------------------------
  346. //    FW_CPrivPictureRep::IsPlatformPictOrphan
  347. //----------------------------------------------------------------------------------------
  348.  
  349. FW_Boolean FW_CPrivPictureRep::IsPlatformPictOrphan() const
  350. {
  351.     return !fOwnPicture;
  352. }
  353.  
  354. //----------------------------------------------------------------------------------------
  355. //    FW_CPrivPictureRep::OrphanPlatformPict
  356. //----------------------------------------------------------------------------------------
  357.  
  358. FW_PlatformPict    FW_CPrivPictureRep::OrphanPlatformPict()
  359. {
  360.     FW_ASSERT(fOwnPicture);        // Cannot orphan twice
  361.     fOwnPicture = FALSE;
  362.     return fPlatformPict;
  363. }
  364.  
  365. //----------------------------------------------------------------------------------------
  366. //    FW_CPrivPictureRep::SetPlatformPict
  367. //----------------------------------------------------------------------------------------
  368.  
  369. void FW_CPrivPictureRep::SetPlatformPict(FW_PlatformPict newPict)
  370. {
  371.     if (fPlatformPict != newPict)
  372.     {
  373.         PrivDisposePict();
  374.         fPlatformPict = newPict;
  375.     }
  376.     
  377.     fOwnPicture = FALSE;
  378. }
  379.  
  380. //----------------------------------------------------------------------------------------
  381. //    FW_CPrivPictureRep::AdoptPlatformPict
  382. //----------------------------------------------------------------------------------------
  383.  
  384. void FW_CPrivPictureRep::AdoptPlatformPict(FW_PlatformPict newPict)
  385. {
  386.     SetPlatformPict(newPict);
  387.     fOwnPicture = TRUE;
  388. }
  389.  
  390. #ifdef FW_BUILD_MAC
  391. //----------------------------------------------------------------------------------------
  392. //    FW_CPrivPictureRep::MacLock
  393. //----------------------------------------------------------------------------------------
  394.  
  395. void FW_CPrivPictureRep::MacLock()
  396. {
  397.     FW_ASSERT(fPlatformPict != NULL);
  398.  
  399.     if (++ fMacLockCount == 1)
  400.         FW_CMemoryManager::LockSystemHandle((FW_PlatformHandle)fPlatformPict);
  401. }
  402. #endif
  403.  
  404. #ifdef FW_BUILD_MAC
  405. //----------------------------------------------------------------------------------------
  406. //    FW_CPrivPictureRep::MacUnlock
  407. //----------------------------------------------------------------------------------------
  408.  
  409. void FW_CPrivPictureRep::MacUnlock()
  410. {
  411.     if (-- fMacLockCount == 0)
  412.         FW_CMemoryManager::UnlockSystemHandle((FW_PlatformHandle)fPlatformPict);    
  413. }
  414. #endif
  415.  
  416. //----------------------------------------------------------------------------------------
  417. //    FW_CPrivPictureRep::PrivReadFrom
  418. //----------------------------------------------------------------------------------------
  419.  
  420. void FW_CPrivPictureRep::PrivReadFrom(FW_CReadableStream& stream)
  421. {
  422. #ifdef FW_BUILD_MAC
  423.     unsigned long picSize;
  424.     stream >> picSize;
  425.     
  426.     fPlatformPict = (FW_PlatformPict) FW_CMemoryManager::AllocateSystemHandle(picSize);
  427.             
  428.     MacLock();
  429.     
  430.     FW_TRY
  431.     {
  432.         stream.Read(*fPlatformPict, picSize);
  433.     }
  434.     FW_CATCH_BEGIN
  435.     FW_CATCH_EVERYTHING()
  436.     {
  437.         MacUnlock();
  438.         ::DisposeHandle((Handle)fPlatformPict);
  439.         fPlatformPict = NULL;
  440.         FW_THROW_SAME();
  441.     }
  442.     FW_CATCH_END
  443.  
  444.     MacUnlock();
  445. #endif
  446. #ifdef FW_BUILD_WIN
  447.     HENHMETAFILE metafile = NULL;
  448.  
  449.     // Check if there is an Aldus metafile header
  450.     SAldusHeader aldusHeader;
  451.     stream.Read(&aldusHeader, sizeof(aldusHeader));
  452.     if(aldusHeader.key == kAldusKey)
  453.     {
  454.         // ----- This is an Aldus format metafile
  455.  
  456.         // Read the header
  457.         METAHEADER mfHeader;
  458.         stream.Read(&mfHeader, sizeof(mfHeader));
  459.  
  460.         // Read the bits
  461.         size_t bitsSize = mfHeader.mtSize * 2L;
  462.         BYTE* bitsBuf = new BYTE[bitsSize];
  463.         
  464.         FW_TRY
  465.         {
  466.             FW_CMemoryManager::CopyMemory(&mfHeader, bitsBuf, sizeof(mfHeader));
  467.             stream.Read(bitsBuf + sizeof(mfHeader), bitsSize - sizeof(mfHeader));
  468.         }
  469.         FW_CATCH_BEGIN
  470.         FW_CATCH_EVERYTHING()
  471.         {
  472.             delete[] bitsBuf;
  473.             FW_THROW_SAME();
  474.         }
  475.         FW_CATCH_END
  476.  
  477.         // Convert an Aldus (Win16) metafile to a Win32 Enhanced Metafile
  478.         METAFILEPICT mfPict;
  479.         mfPict.mm = MM_ANISOTROPIC;
  480.         mfPict.xExt = (aldusHeader.bbox.right - aldusHeader.bbox.left) * 2540 / aldusHeader.inch;
  481.         mfPict.yExt = (aldusHeader.bbox.bottom - aldusHeader.bbox.top) * 2540 / aldusHeader.inch;
  482.  
  483.         metafile = ::SetWinMetaFileBits(bitsSize, bitsBuf, NULL, &mfPict);
  484.         delete[] bitsBuf;
  485.     }
  486.     else
  487.     {
  488.         // ----- Not an Aldus metafile, try Win32 Enhanced metafile
  489.  
  490.         // Read the header
  491.         ENHMETAHEADER enhHeader;
  492.         FW_CMemoryManager::CopyMemory(&aldusHeader, &enhHeader, sizeof(aldusHeader));
  493.         stream.Read((char*) &enhHeader + sizeof(aldusHeader), sizeof(enhHeader) - sizeof(aldusHeader));
  494.  
  495.         // Verify the header
  496.         if(enhHeader.iType == EMR_HEADER || enhHeader.nSize == sizeof(enhHeader))
  497.         {
  498.             // Read the bits
  499.             size_t bitsSize = enhHeader.nBytes;
  500.             BYTE* bitsBuf = new BYTE[bitsSize];
  501.             FW_TRY
  502.             {
  503.                 FW_CMemoryManager::CopyMemory(&enhHeader, bitsBuf, sizeof(enhHeader));
  504.                 stream.Read(bitsBuf + sizeof(enhHeader), bitsSize - sizeof(enhHeader));
  505.             }
  506.             FW_CATCH_BEGIN
  507.             FW_CATCH_EVERYTHING()
  508.             {
  509.                 delete[] bitsBuf;
  510.                 FW_THROW_SAME();
  511.             }
  512.             FW_CATCH_END
  513.     
  514.             // Create a metafile and set the bits
  515.              metafile = ::SetEnhMetaFileBits(bitsSize, bitsBuf);
  516.             delete[] bitsBuf;
  517.         }
  518.     }
  519.  
  520.     if(metafile == NULL)
  521.         FW_Failure(FW_xInvalidPictureData);
  522.  
  523.     // Save metafile info
  524.     AdoptPlatformPict(metafile);
  525. #endif
  526. }
  527.  
  528. //----------------------------------------------------------------------------------------
  529. //    FW_CPrivPictureRep::PrivDisposePict
  530. //----------------------------------------------------------------------------------------
  531.  
  532. void FW_CPrivPictureRep::PrivDisposePict()
  533. {
  534.     if (fOwnPicture && fPlatformPict != NULL)
  535.     {
  536. #ifdef FW_BUILD_MAC
  537.         ::KillPicture(fPlatformPict);
  538. #endif
  539. #ifdef FW_BUILD_WIN
  540.         ::DeleteEnhMetaFile(fPlatformPict);
  541. #endif
  542.     }
  543.  
  544.     fPlatformPict = NULL;
  545. }
  546.